extends Control

@onready var level_label: Label = $LevelLabel
@onready var empty_bar: Panel = $EmptyBar
@onready var filled_bar: Panel = $FilledBar
@onready var exp_particles: CPUParticles2D = $ExpParticles

var player_stats: PlayerStats = null
var prev_exp_value: float = 0
var _last_printed_ratio: float = -1.0
var _bar_width: float = 200.0  # 经验条总宽度
var _flash_timer: float = 0.0  # 闪光效果计时器
var _shader_material: ShaderMaterial = null

func _ready():
	print("玩家节点初始化...")
	# 等待一帧确保玩家节点已经初始化
	await get_tree().process_frame
	
	# 获取玩家节点的 stats
	var player = get_tree().get_first_node_in_group("player")
	if player:
		player_stats = player.stats
		print("获取到玩家stats：", player_stats)
	else:
		print("未找到玩家节点")
	
	# 连接升级信号
	if player_stats:
		player_stats.connect("level_up", Callable(self, "_on_level_up"))
		print("成功连接升级信号")
	
	# 初始化经验条宽度
	_bar_width = empty_bar.size.x
	
	# 初始化粒子效果
	_setup_particles()
	
	# 设置经验条着色器
	_setup_exp_bar_shader()
	
	_update_ui()

func _setup_exp_bar_shader():
	# 创建着色器材质
	_shader_material = ShaderMaterial.new()
	
	# 着色器代码
	var shader_code = """
	shader_type canvas_item;
	
	// 基础颜色
	uniform vec4 base_color : source_color = vec4(0.0, 0.3, 0.8, 1.0);
	
	// 闪光颜色
	uniform vec4 flash_color : source_color = vec4(0.7, 0.9, 1.0, 1.0);
	
	// 闪光位置 (0.0 到 1.0)
	uniform float flash_position : hint_range(0.0, 1.0) = 0.0;
	
	// 闪光宽度
	uniform float flash_width : hint_range(0.01, 0.5) = 0.1;
	
	// 闪光强度
	uniform float flash_intensity : hint_range(0.0, 1.0) = 0.7;
	
	void fragment() {
		// 计算当前像素的水平位置 (0.0 到 1.0)
		float pos_x = UV.x;
		
		// 计算当前像素到闪光中心的距离
		float dist = abs(pos_x - flash_position);
		
		// 如果在闪光范围内
		if (dist < flash_width) {
			// 计算闪光强度 - 中心最亮，边缘渐弱
			float intensity = (1.0 - dist / flash_width) * flash_intensity;
			
			// 混合基础颜色和闪光颜色
			COLOR = mix(base_color, flash_color, intensity);
		} else {
			// 使用基础颜色
			COLOR = base_color;
		}
	}
	"""
	
	# 设置着色器代码
	var shader = Shader.new()
	shader.code = shader_code
	_shader_material.shader = shader
	
	# 应用着色器材质到填充条
	filled_bar.material = _shader_material

func _setup_particles():
	if !exp_particles:
		# 如果场景中没有粒子节点，则创建一个
		exp_particles = CPUParticles2D.new()
		add_child(exp_particles)
	
	# 配置粒子属性
	exp_particles.emitting = false
	exp_particles.amount = 20
	exp_particles.lifetime = 0.8
	exp_particles.explosiveness = 0.2
	exp_particles.randomness = 0.5
	exp_particles.local_coords = false
	exp_particles.draw_order = CPUParticles2D.DRAW_ORDER_INDEX
	
	# 粒子外观
	exp_particles.direction = Vector2(0, -1)
	exp_particles.spread = 45.0
	exp_particles.gravity = Vector2(0, 20)
	exp_particles.initial_velocity_min = 20.0
	exp_particles.initial_velocity_max = 40.0
	exp_particles.scale_amount_min = 1.0
	exp_particles.scale_amount_max = 2.0
	exp_particles.color = Color(0.2, 0.5, 1.0, 0.8)

func _process(delta):
	if player_stats:
		_update_ui()
		_update_particles()
		_update_flash_effect(delta)

func _update_flash_effect(delta):
	# 更新闪光效果
	_flash_timer += delta * 0.5  # 控制闪光速度
	
	# 计算闪光位置 (0.0 到 1.0 循环)
	var flash_position = fmod(_flash_timer, 1.5)
	
	# 如果闪光位置超过1.0，则重置为-0.2（闪光宽度外），这样闪光会完全消失后再从左侧出现
	if flash_position > 1.0:
		flash_position = -0.2
		_flash_timer = -0.4  # 重置计时器，使闪光完全离开后再进入
	
	# 更新着色器参数
	if _shader_material:
		_shader_material.set_shader_parameter("flash_position", flash_position)

func _update_ui():
	if player_stats == null:
		print("player_stats 为空，无法更新UI")
		return

	# 更新等级和经验值显示
	level_label.text = "等级：" + str(player_stats.level) + "   经验：" + str(player_stats.current_exp) + "/" + str(player_stats.exp_to_next)
	
	# 计算填充比例
	var fill_ratio = float(player_stats.current_exp) / float(player_stats.exp_to_next)
	fill_ratio = clamp(fill_ratio, 0.0, 1.0)
	
	# 平滑过渡填充宽度
	var target_width = _bar_width * fill_ratio
	var current_width = filled_bar.size.x
	var new_width = lerp(current_width, target_width, 0.1)
	
	# 更新填充条宽度
	filled_bar.size.x = new_width
	
	# 调试输出
	if Engine.is_editor_hint() or OS.is_debug_build():
		if abs(fill_ratio - _last_printed_ratio) > 0.01:
			print("经验条比率: ", fill_ratio, " 值: ", player_stats.current_exp, "/", player_stats.exp_to_next)
			_last_printed_ratio = fill_ratio

func _update_particles():
	# 检测经验值是否增加
	if player_stats.current_exp > prev_exp_value:
		# 经验增加时触发粒子效果
		_emit_exp_particles()
	
	prev_exp_value = float(player_stats.current_exp)

func _emit_exp_particles():
	# 计算粒子发射位置（基于经验条的填充程度）
	var fill_ratio = float(player_stats.current_exp) / float(player_stats.exp_to_next)
	var emit_pos_x = empty_bar.position.x + (filled_bar.size.x)
	
	# 确保粒子只在填充部分发射
	if fill_ratio > 0.01:  # 只有当填充比例大于1%时才发射粒子
		exp_particles.position = Vector2(emit_pos_x, empty_bar.position.y + empty_bar.size.y / 2)
		
		# 触发粒子发射
		exp_particles.emitting = true
		
		# 0.3秒后停止发射
		await get_tree().create_timer(0.3).timeout
		exp_particles.emitting = false

func _on_level_up(new_level):
	# 升级消息处理（这里简单打印消息并更新显示）
	print("玩家升级！当前等级：", new_level)
	level_label.text = "等级：" + str(new_level)
	
	# 播放升级特效
	_play_level_up_effect()

func _play_level_up_effect():
	# 创建一个临时的粒子爆发效果
	var level_up_particles = CPUParticles2D.new()
	add_child(level_up_particles)
	
	# 设置粒子位置在经验条中心
	level_up_particles.position = Vector2(empty_bar.position.x + empty_bar.size.x / 2, empty_bar.position.y + empty_bar.size.y / 2)
	
	# 配置粒子属性 - 升级时的爆炸效果
	level_up_particles.emitting = true
	level_up_particles.one_shot = true
	level_up_particles.amount = 50
	level_up_particles.lifetime = 2.0
	level_up_particles.explosiveness = 0.8
	level_up_particles.randomness = 0.5
	level_up_particles.local_coords = false
	
	# 粒子外观 - 金色/黄色爆炸效果
	level_up_particles.direction = Vector2(0, 0)  # 全方向扩散
	level_up_particles.spread = 180.0
	level_up_particles.gravity = Vector2(0, 20)
	level_up_particles.initial_velocity_min = 50.0
	level_up_particles.initial_velocity_max = 100.0
	level_up_particles.scale_amount_min = 2.0
	level_up_particles.scale_amount_max = 4.0
	level_up_particles.color = Color(1.0, 0.8, 0.2, 0.8)  # 金色
	
	# 2秒后移除粒子节点
	await get_tree().create_timer(2.0).timeout
	level_up_particles.queue_free()

func _find_player_stats():
	for player in get_tree().get_nodes_in_group("player"):
		player_stats = player.stats
		break
	if player_stats:
		# 连接升级信号，收到升级消息后更新 UI 或播放特效
		player_stats.connect("level_up", Callable(self, "_on_level_up")) 
	var players = get_tree().get_nodes_in_group("player")
	print("找到玩家组数量:", players.size())
	for player in players:
		print("玩家节点：", player.name)
		# 检查玩家节点是否包含 stats 属性
		if "stats" in player:
			player_stats = player.stats
			print("找到玩家 stats:", player_stats)
			break
	if player_stats:
		player_stats.connect("level_up", Callable(self, "_on_level_up"))
	else:
		print("未找到玩家 stats，请确认玩家是否已加入 'player' 分组")
